Technote 1158

Levatatus Interruptus*
PowerPC ïÇìÆè¨êîì_ÉåÉWÉXÉ^ÇÃëfiîï˚ñ@

(*ñüâÊÇÃÉLÉÉÉâÉNÉ^Å[Ç™äRÇ©ÇÁîÚÇ—èoǵÇΩÇΔÇ´ÅAâ∫Çå©ÇƒÇ©ÇÁÇ≈ǻǢÇΔóéÇøÇ»Ç¢Ç±ÇΔÇΔÇÕä÷åWdžÇËÇ‹ÇπÇÒÅB)


ñ⁄éü

ñ‚ëËÅFäˆî≠ê´ FP ÉåÉWÉXÉ^ÇÃëfiîǵñYÇÍ

ÉTÉìÉvÉã

The Glue Code

ÉfÉBÉXÉAÉZÉìÉuÉãÇΔâêÕ

êVǵǢÉTÉìÉvÉã (â¸ó«çœ)

êVǵǢâêÕ (â¸ó«çœ)

êVǵǢÉOÉãÅ[ÉRÅ[Éh (â¸ó«çœ)

Ç‹ÇΔÇfl

ïÇìÆè¨êîì_ñΩóflÇÃégópÇÕí èÌÅAäJî≠ÉVÉXÉeÉÄÇÃÉâÉCÉuÉâÉäÇ…ÇÊǡǃèàóùÇ≥ÇÍÇ‹Ç∑ÅBDZǧǵÇΩÉâÉCÉuÉâÉäÇ…ÇÊǡǃê≥ǵÇ≠èàóùÇ≥ÇÍǻǢì¡ï Ç»ÉPÅ[ÉXÇà 1 ǬDžÅAäÑÇËçûÇ›ÉãÅ[É`ÉìÇ™çsǧäˆî≠ê´ïÇìÆè¨êîì_ (FP) ÉåÉWÉXÉ^ÇÃëfiîÇΔïúå≥ǙdžÇËÇ‹Ç∑ÅBDZÇÃèÍçáÅAïÇìÆè¨êîì_ÇàµÇ§ÉAÉZÉìÉuÉäÉRÅ[ÉhÇèëÇ≠ïKóvǙdžÇËÇ‹Ç∑ÅBDZÇÃÉeÉNÉjÉJÉãÉmÅ[ÉgÇÕDZÇÍDžǬǢǃê‡ñæÇµÇ‹Ç∑ÅB

DZÇÃÉeÉNÉjÉJÉãÉmÅ[ÉgÇÕÅAïÇìÆè¨êîì_ÉåÉWÉXÉ^ÇégópÇ∑ÇÈÅAPowerPC ÇÃäÑÇËçûÇ›ÉãÅ[É`ÉìÇçÏê¨Ç∑ÇÈÉfÉxÉçÉbÉpÇ…å¸ÇØÇΩLJÇÃÇ≈Ç∑ÅB



ñ‚ëËÅFäˆî≠ê´ FP ÉåÉWÉXÉ^ÇÃëfiîǵñYÇÍ

PowerPC ÇÃäÑÇËçûÇ›ÉfÉBÉXÉpÉbÉ`ÉÉÇÕÅAäˆî≠ê´îƒópÉåÉWÉXÉ^ (GPR0Å`12) ÇÃëfiîÇΔïúå≥ÇÕçsǢNjÇ∑Ç™ÅAäˆî≠ê´ïÇìÆè¨êîì_ÉåÉWÉXÉ^ (FPR0Å`13) Ç…ëŒÇµÇƒÇÕDZÇÍÇçsǢNjÇπÇÒ (*)ÅBDZÇÃÇΩÇflÅAäˆî≠ê´ïÇìÆè¨êîì_ÉåÉWÉXÉ^ÇégópÇ∑ÇÈ PowerPC ÇÃäÑÇËçûÇ›ÉãÅ[É`ÉìÇÕÇ∑Ç◊ǃÅADZÇÃëfiîÇΔïúå≥ÇçsÇÌÇ»ÇØÇÍnjǻÇËÇ‹ÇπÇÒÅBǪǧǵǻǢÇΔÅAäÑÇËçûÇ‹ÇÍÇΩë§ÇÃÉãÅ[É`ÉìÇÕÅAäÑÇËçûÇ›ÉRÅ[ÉhÇ…ÇÊÇËó\ä˙ÇπÇ∏DZÇÍÇÁÇÃÉåÉWÉXÉ^Ç™ïœçXÇ≥ÇÍǃǵNjǧDZÇΔÇ…Ç»ÇËÇ‹Ç∑ÅB

* îÒäˆî≠ê´ÉåÉWÉXÉ^ÇÕÇ∑Ç◊ǃäÑÇËçûÇ›ÉãÅ[É`ÉìÇÃÉvÉçÉçÅ[ÉOÇ≈ëfiîÇ≥ÇÍÅAÉGÉsÉçÅ[ÉOÇ≈ïúå≥Ç≥ÇÍÇ‹Ç∑ÅBDZÇÃÉRÅ[ÉhÇÕÉRÉìÉpÉCÉâÇ™é©ìÆê∂ê¨ÇµÇ‹Ç∑ÅB


ÉTÉìÉvÉã

éüÇ…åfç⁄Ç∑ÇÈÇÃÇÕÅAïÇìÆè¨êîì_ÉåÉWÉXÉ^ (äˆî≠ê´Ç®ÇÊÇ—îÒäˆî≠ê´ÇÃóºï˚) ÇégópÇ∑ÇÈäÑÇËçûÇ›ÉãÅ[É`ÉìÇÃÉTÉìÉvÉãÇ≈Ç∑ÅB


pascal void My_SIInterruptProc(SPBPtr inParamPtr,Ptr dataBuffer,SInt16 peakAmplitude,
SInt32 sampleSize)
{
	float tPIE1 = 0.0f;
	float tPIE2 = 0.0f;
	Ptr tPtr = dataBuffer;
	SInt32 count = inParamPtr->bufferLength;
 
	while (count--)
	{
		*tPtr++ ^= 0x80;
		tPIE1 += (tPIE1 + 1.0f) * 1.1f;
		tPIE2 += (tPIE1 + 1.0f) * 1.1f;
	}
}

âêÕ

DZÇÃäÑÇËçûÇ›ÉãÅ[É`ÉìÇÃÉfÉBÉXÉAÉZÉìÉuÉãÇΔâêÕÇéüÇ…é¶ÇµÇ‹Ç∑ÅB


pascal void My_SIInterruptProc(SPBPtr inParamPtr,Ptr dataBuffer,SInt16 peakAmplitude,
SInt32 sampleSize)
{
00000000: DBE1FFF8  stfd     fp31,-8(SP)        // äˆî≠ê´ FP ÉåÉWÉXÉ^ (fp30-31) ÇÃï€ë∂
00000004: DBC1FFF0  stfd     fp30,-16(SP)
00000008: 93E1FFEC  stw      r31,-20(SP)        // äˆî≠ê´ GP ÉåÉWÉXÉ^ (r30-31) ÇÃï€ë∂
0000000C: 93C1FFE8  stw      r30,-24(SP)
 float tPIE1 = 0.0f;
00000010: C3E20000  lfs      fp31,@1360(RTOC)   // äˆî≠ê´ FP ÉåÉWÉXÉ^ÇÃÉçÅ[Éh
 float tPIE2 = 0.0f;
00000014: C3C20000  lfs      fp30,@1360(RTOC)
 Ptr tPtr = dataBuffer;
00000018: 7C9F2378  mr       r31,r4             // É|ÉCÉìÉ^ÇÉoÉbÉtÉ@Ç…ÉçÅ[Éh
 SInt32 count = inParamPtr->bufferLength;
0000001C: 83C3000C  lwz      r30,12(r3)
 while (count--)
 {
00000020: 48000038  b        *+56                    ; $00000058
  *tPtr++ ^= 0x80;
00000024: 7FE5FB78  mr       r5,r31
00000028: 3BFF0001  addi     r31,r31,1
0000002C: 88050000  lbz      r0,0(r5)
00000030: 6800FF80  xori     r0,r0,$ff80
00000034: 98050000  stb      r0,0(r5)
  tPIE1 += (tPIE1 + 1.0f) * 1.1f;
00000038: C0220000  lfs      fp1,@1361(RTOC)    // íçà”: îÒäˆî≠ê´ FP ÉåÉWÉXÉ^ (fp1) ÇÃégóp
0000003C: C0020000  lfs      fp0,@1362(RTOC)    // " (fp0)
00000040: EC00F82A  fadds    fp0,fp0,fp31       // " (fp0)
00000044: EFE1F83A  fmadds   fp31,fp1,fp0,fp31  // " (fp0-1)
  tPIE2 += (tPIE1 + 1.0f) * 1.1f;
00000048: C0220000  lfs      fp1,@1361(RTOC)    // " (fp1)
0000004C: C0020000  lfs      fp0,@1362(RTOC)    // " (fp0)
00000050: EC00F82A  fadds    fp0,fp0,fp31       // " (fp0)
00000054: EFC1F03A  fmadds   fp30,fp1,fp0,fp30  // " (fp0-1)
 }
00000058: 2C1E0000  cmpwi    r30,0              // count ÇÃåüç∏
0000005C: 3BDEFFFF  subi     r30,r30,1          // count ÇÃçXêV
00000060: 4082FFC4  bne      *-60 ; $00000024   // (É[ÉçÇ…Ç»ÇÈÇ‹Ç≈ÉãÅ[Év)
         
00000064: CBE1FFF8  lfd      fp31,-8(SP)        // äˆî≠ê´ FP ÉåÉWÉXÉ^ (fp30-31) ÇÃïúå≥
00000068: CBC1FFF0  lfd      fp30,-16(SP)
0000006C: 83E1FFEC  lwz      r31,-20(SP)        // äˆî≠ê´ GP ÉåÉWÉXÉ^ (r30-31) ÇÃïúå≥
00000070: 83C1FFE8  lwz      r30,-24(SP)
00000074: 4E800020  blr                         // ñflÇÈ (ÉäÉìÉNÉåÉWÉXÉ^Ç…ï™äÚ)
}

DZDZÇ≈ÇÃñ‚ëËÇÕîÒäˆî≠ê´ïÇìÆè¨êîì_ÉåÉWÉXÉ^ (FP0Å`1) Ç™ÅAÉvÉçÉçÅ[ÉOÉRÅ[ÉhÇΔÉGÉsÉçÅ[ÉOÉRÅ[ÉhÇ≈ëfiîÅAïúå≥Ç≥ÇÍǻǢDZÇΔÇ≈Ç∑ÅBDZÇÃÉãÅ[É`ÉìÇ…äÑÇËçûÇ‹ÇÍÇΩÉRÅ[ÉhÇ≈ÇÕÇ«ÇÍLJÅAFP0Å`1 Ç…ó\ä˙ÇπÇ ílÇ™åªÇÍÇÈDZÇΔÇ…Ç»ÇËÇ‹Ç∑ÅB


ÉOÉãÅ[ÉRÅ[Éh

DZÇÃÉeÉNÉjÉJÉãÉmÅ[ÉgÇ≈ÇÕÅAäˆî≠ê´ïÇìÆè¨êîì_ÉåÉWÉXÉ^ÇÃëfiîÇΔïúå≥Ççsǧ PowerPC ÇÃÉAÉZÉìÉuÉäÉRÅ[ÉhÇèëÇ≠ÇΔǢǧâåàçÙÇíÒàƒÇµÇ‹Ç∑ÅBã…í[Ç…êTèdÇ»ï˚ñ@ÇΔǵǃÇÕäˆî≠ê´ FP ÉåÉWÉXÉ^ÇÇ∑Ç◊ǃëfiîïúå≥Ç∑ÇÈÇΔǢǧï˚ñ@ǙdžÇËÇ‹Ç∑ÅB(îÒäˆî≠ê´ FP ÉåÉWÉXÉ^Çà FP14Å`31 ÇÕäÑÇËçûÇ›ÉãÅ[É`ÉìÇÃÉvÉçÉçÅ[ÉOÉRÅ[ÉhÇΔÉGÉsÉçÅ[ÉOÉRÅ[ÉhÇ≈ëfiîÇ≥ÇÍÇ‹Ç∑ÅB) ǵǩǵÅAì«é“ÇÃÉãÅ[É`ÉìÇ™ÇΩÇΔǶnj (ÉTÉìÉvÉãÇΔìØÇ∂ÇÊǧDž)ÅAäˆî≠ê´ FP ÉåÉWÉXÉ^Çà FP0 ÇΔ FP1 ǵǩégÇÌǻǢèÍçáÅAǪÇÍÇÁÇÃÉåÉWÉXÉ^ÇæÇØÇëfiî/ïúå≥Ç∑ÇÈÇÊǧç\ë¢ëÃÇè¨Ç≥Ç≠Ç∑Ç◊Ç´Ç≈Ç∑ÅBǵǩǵÅAFP SCR Çëfiîïúå≥Ç∑ÇÈçsÇçÌèúǵǃÇÕÇ¢ÇØÇ‹ÇπÇÒÅBDZÇÍÇÕèÌÇ…ïKóvǻDZÇΔÇæÇ©ÇÁÇ≈Ç∑ÅBç≈èâÇ…ã…í[Ç…êTèdÇ»âåàçÙÇÃǟǧÇé¶ÇµÇ‹Ç∑ÅB


#if TARGET_CPU_PPC
typedef struct FPURegs
{
 float FPR00;
 float FPR01;
 float FPR02;
 float FPR03;
 float FPR04;
 float FPR05;
 float FPR06;
 float FPR07;
 float FPR08;
 float FPR09;
 float FPR10;
 float FPR11;
 float FPR12;
 float FPR13;
 float FPSCR;
} FPURegsRec,*FPURegsPtr,**FPURegsHdl;
         
// ä÷êîÉvÉçÉgÉ^ÉCÉv
asm void SavePowerPCVolatileFPRs(FPURegsPtr pFPURegsPtr);
asm void RestorePowerPCVolatileFPRs(FPURegsPtr pFPURegsPtr);
         
//
// PowerPC ÇÃîÒäˆî≠ê´ïÇìÆè¨êîì_ÉåÉWÉXÉ^ÇìnÇ≥ÇÍÇΩç\ë¢ëÃÇ…ï€ë∂
//
         
asm void SavePowerPCVolatileFPRs(FPURegsPtr pFPURegsPtr)
{
 stfd fp0,FPURegs.FPR00(r3)
 stfd fp1,FPURegs.FPR01(r3)
 stfd fp2,FPURegs.FPR02(r3)
 stfd fp3,FPURegs.FPR03(r3)
 stfd fp4,FPURegs.FPR04(r3)
 stfd fp5,FPURegs.FPR05(r3)
 stfd fp6,FPURegs.FPR06(r3)
 stfd fp7,FPURegs.FPR07(r3)
 stfd fp8,FPURegs.FPR08(r3)
 stfd fp9,FPURegs.FPR09(r3)
 stfd fp10,FPURegs.FPR10(r3)
 stfd fp11,FPURegs.FPR11(r3)
 stfd fp12,FPURegs.FPR12(r3)
 stfd fp13,FPURegs.FPR13(r3)
         
    mffs    fp0                                 // fpscr Ç fp0 Ç…ÉRÉsÅ[
    stfd    fp0,FPURegs.FPSCR(r3)               // fpscr Çï€ë∂
 blr
}
         
//
// ìnÇ≥ÇÍÇΩç\ë¢ëÃÇ©ÇÁ PowerPC ÇÃîÒäˆî≠ê´ïÇìÆè¨êîì_ÉåÉWÉXÉ^Çïúå≥Ç∑ÇÈ
//
         
asm void RestorePowerPCVolatileFPRs(FPURegsPtr pFPURegsPtr)
{
 lfd fp0,  FPURegs.FPSCR(r3)            // ï€ë∂ǵÇΩ fpscr Ç fp0 Ç…ÉçÅ[Éh
 mtfsf 0xff, fp0                          // ǪÇÍÇ fpscr Ç…ñflÇ∑
         
 lfd  fp0, FPURegs.FPR00(r3)
 lfd  fp1, FPURegs.FPR01(r3)
 lfd  fp2, FPURegs.FPR02(r3)
 lfd  fp3, FPURegs.FPR03(r3)
 lfd  fp4, FPURegs.FPR04(r3)
 lfd  fp5, FPURegs.FPR05(r3)
 lfd  fp6, FPURegs.FPR06(r3)
 lfd  fp7, FPURegs.FPR07(r3)
 lfd  fp8, FPURegs.FPR08(r3)
 lfd  fp9, FPURegs.FPR09(r3)
 lfd  fp10, FPURegs.FPR10(r3)
 lfd  fp11, FPURegs.FPR11(r3)
 lfd  fp12, FPURegs.FPR12(r3)
 lfd  fp13, FPURegs.FPR13(r3)
 blr
}
#endif // #if TARGET_CPU_PPC

êVǵǢÉTÉìÉvÉã (â¸ó«çœ)

äˆî≠ê´ FP ÉåÉWÉXÉ^Çëfiîïúå≥Ç∑ÇÈÉãÅ[É`ÉìÇåƒÇ—èoÇ∑çsÇÉTÉìÉvÉãÇ…í«â¡Ç∑ÇÈÇΔÅAéüÇÃÇÊǧDžǻÇËÇ‹Ç∑ÅB


pascal void My_SIInterruptProc(SPBPtr inParamPtr,Ptr dataBuffer,SInt16 peakAmplitude,
SInt32 sampleSize)
{
#if TARGET_CPU_PPC
	FPURegsRec tFPURegsRec;
	SavePowerPCVolatileFPRs(&tFPURegsRec);
	{
#endif
		float tPIE1 = 3.14159f;
		float tPIE2 = 3.14159f;
 
		Ptr tPtr = dataBuffer;
		SInt32 count = inParamPtr->bufferLength;
		while (count--)
		{
			*tPtr++ ^= 0x80;
			tPIE1 += (tPIE1 + 1.0f) * 1.1f;
			tPIE2 += (tPIE1 + 1.0f) * 1.1f;
		}
#if TARGET_CPU_PPC
	}
	RestorePowerPCVolatileFPRs(&tFPURegsRec);
#endif
}
 

êVǵǢâêÕ (â¸ó«çœ)

éüÇ…åfç⁄Ç∑ÇÈÇÃÇÕÅAêVǵǢ (ǵǩLJâ¸ó«çœÇ›) ÉãÅ[É`ÉìÇÃÉfÉBÉXÉAÉZÉìÉuÉãÇΔâêÕÇ≈Ç∑ÅB


pascal void My_SIInterruptProc(SPBPtr inParamPtr,Ptr dataBuffer,SInt16 peakAmplitude,
SInt32 sampleSize)
{
 FPURegsRec tFPURegsRec;
00000000: 7C0802A6  mflr     r0                 // ÉäÉìÉNÉåÉWÉXÉ^Ç R0 Ç…à⁄Ç∑
00000004: DBE1FFF8  stfd     fp31,-8(SP)        // äˆî≠ê´ FP ÉåÉWÉXÉ^ (fp30-31) Çï€ë∂
00000008: DBC1FFF0  stfd     fp30,-16(SP)
0000000C: 93E1FFEC  stw      r31,-20(SP)        // äˆî≠ê´ GP ÉåÉWÉXÉ^Çï€ë∂
regs (r30-31)
00000010: 93C1FFE8  stw      r30,-24(SP)
00000014: 90010008  stw      r0,8(SP)           // ÉäÉìÉNÉåÉWÉXÉ^Çï€ë∂
00000018: 9421FF70  stwu     SP,-144(SP)        // ÉXÉ^ÉbÉNÉ|ÉCÉìÉ^Çï€ë∂
0000001C: 906100A8  stw      r3,168(SP)         // ç≈èâÇà 2 ǬÇÃÉpÉâÉÅÅ[É^Çï€ë∂
00000020: 908100AC  stw      r4,172(SP)
 SavePowerPCVolatileFPRs(&tFPURegsRec);
 {
00000024: 38610038  addi     r3,SP,56           // r3 ÇÉXÉ^ÉbÉNè„Çà tFPURegsRec Ç…ê›íË
00000028: 48000001  bl       .SavePowerPCVolatileFPRs
                                                // ï€ë∂ǵÇΩÉãÅ[É`ÉìÇåƒÇ—èoÇ∑
  float tPIE1 = 0.0f;
0000002C: C3E20000  lfs      fp31,@1360(RTOC)   // äˆî≠ê´ FP ÉåÉWÉXÉ^ÇÉçÅ[Éh
  float tPIE2 = 0.0f;
00000030: C3C20000  lfs      fp30,@1360(RTOC)
        Ptr tPtr = dataBuffer;                  // É|ÉCÉìÉ^Ç…ÉoÉbÉtÉ@ÇÉçÅ[Éh
00000034: 83E100AC  lwz      r31,172(SP)
  SInt32 count = inParamPtr->bufferLength;
00000038: 806100A8  lwz      r3,168(SP)
0000003C: 83C3000C  lwz      r30,12(r3)
  while (count--)
  {
00000040: 48000038  b        *+56                    ; $00000078
   *tPtr++ ^= 0x80;
00000044: 7FE3FB78  mr       r3,r31
00000048: 3BFF0001  addi     r31,r31,1
0000004C: 88030000  lbz      r0,0(r3)
00000050: 6800FF80  xori     r0,r0,$ff80
00000054: 98030000  stb      r0,0(r3)
   tPIE1 += (tPIE1 + 1.0f) * 1.1f;
00000058: C0220000  lfs      fp1,@1361(RTOC)    // íçà”: îÒäˆî≠ê´ FP ÉåÉWÉXÉ^ (fp1) Çégóp
0000005C: C0020000  lfs      fp0,@1362(RTOC)    // " (fp0)
00000060: EC00F82A  fadds    fp0,fp0,fp31       // " (fp0)
00000064: EFE1F83A  fmadds   fp31,fp1,fp0,fp31  // " (fp0-1)
   tPIE2 += (tPIE1 + 1.0f) * 1.1f;
00000068: C0220000  lfs      fp1,@1361(RTOC)    // " (fp1)
0000006C: C0020000  lfs      fp0,@1362(RTOC)    // " (fp0)
00000070: EC00F82A  fadds    fp0,fp0,fp31       // " (fp0)
00000074: EFC1F03A  fmadds   fp30,fp1,fp0,fp30  // " (fp0-1)
  }
 }
00000078: 2C1E0000  cmpwi    r30,0              // count ÇÃåüç∏
0000007C: 3BDEFFFF  subi     r30,r30,1          // count ÇÃçXêV
00000080: 4082FFC4  bne      *-60                    ; $00000044
                                                // (É[ÉçÇ…Ç»ÇÈÇ‹Ç≈ÉãÅ[Év)
 RestorePowerPCVolatileFPRs(&tFPURegsRec);
00000084: 38610038  addi     r3,SP,56           // r3 ÇÉXÉ^ÉbÉNè„Çà tFPURegsRec Ç…ê›íË
00000088: 48000001  bl       .RestorePowerPCVolatileFPRs
                                                // ï€ë∂ǵÇΩÉãÅ[É`ÉìÇåƒÇ—èoÇ∑
         
0000008C: 80010098  lwz      r0,152(SP)         // ñflÇËÉAÉhÉåÉX Å® r0
00000090: 38210090  addi     SP,SP,144          // ÉXÉ^ÉbÉNÇÃí≤êÆ
00000094: CBE1FFF8  lfd      fp31,-8(SP)        // äˆî≠ê´ FP ÉåÉWÉXÉ^ (fp30-31) ÇÃïúå≥
00000098: CBC1FFF0  lfd      fp30,-16(SP)
0000009C: 7C0803A6  mtlr     r0                 // ñflÇËÉAÉhÉåÉXÇÉäÉìÉNÉåÉWÉXÉ^Ç…à⁄Ç∑
000000A0: 83E1FFEC  lwz      r31,-20(SP)        // äˆî≠ê´ GP ÉåÉWÉXÉ^ (r30-31) Çïúå≥
000000A4: 83C1FFE8  lwz      r30,-24(SP)
000000A8: 4E800020  blr                         // ñflÇÈ (ÉäÉìÉNÉåÉWÉXÉ^Ç…ï™äÚ)
         

êVǵǢÉOÉãÅ[ÉRÅ[Éh (â¸ó«çœ)

DZÇÃÉTÉìÉvÉãÉãÅ[É`ÉìÇ™égópÇ∑ÇÈÇÃÇÕäˆî≠ê´ FP ÉåÉWÉXÉ^Çà FP0 ÇΔ FP1 ÇæÇØÇ»ÇÃÇ≈ÅAÉOÉãÅ[ÉRÅ[ÉhÇÃç\ë¢ëÃÇè¨Ç≥Ç≠ǵÅAïKóvÇ»ÉåÉWÉXÉ^ÇæÇØÇëfiîïúå≥Ç∑ÇÍÇŒçœÇ›Ç‹Ç∑ÅBéüÇ…ç≈ìKâªÇµÇΩÉRÅ[ÉhÇé¶ÇµÇ‹Ç∑ÅB


#if TARGET_CPU_PPC
typedef struct FPURegs
{
 float FPR00;
 float FPR01;
/*
 float FPR02;
 float FPR03;
 float FPR04;
 float FPR05;
 float FPR06;
 float FPR07;
 float FPR08;
 float FPR09;
 float FPR10;
 float FPR11;
 float FPR12;
 float FPR13;
*/
 float FPSCR;
} FPURegsRec,*FPURegsPtr,**FPURegsHdl;
         
// ä÷êîÉvÉçÉgÉ^ÉCÉv
asm void SavePowerPCVolatileFPRs(FPURegsPtr pFPURegsPtr);
asm void RestorePowerPCVolatileFPRs(FPURegsPtr pFPURegsPtr);
         
//
// PowerPC ÇÃîÒäˆî≠ê´ïÇìÆè¨êîì_ÉåÉWÉXÉ^ÇìnÇ≥ÇÍÇΩç\ë¢ëÃÇ…ï€ë∂Ç∑ÇÈ
//
         
asm void SavePowerPCVolatileFPRs(FPURegsPtr pFPURegsPtr)
{
 stfd fp0,FPURegs.FPR00(r3)
 stfd fp1,FPURegs.FPR01(r3)
/*
 stfd fp2,FPURegs.FPR02(r3)
 stfd fp3,FPURegs.FPR03(r3)
 stfd fp4,FPURegs.FPR04(r3)
 stfd fp5,FPURegs.FPR05(r3)
 stfd fp6,FPURegs.FPR06(r3)
 stfd fp7,FPURegs.FPR07(r3)
 stfd fp8,FPURegs.FPR08(r3)
 stfd fp9,FPURegs.FPR09(r3)
 stfd fp10,FPURegs.FPR10(r3)
 stfd fp11,FPURegs.FPR11(r3)
 stfd fp12,FPURegs.FPR12(r3)
 stfd fp13,FPURegs.FPR13(r3)
*/
    mffs    fp0                                 // fpscr Ç fp0 Ç…ÉRÉsÅ[
    stfd    fp0,FPURegs.FPSCR(r3)               // fpscr Çï€ë∂
 blr
}
         
//
// ìnÇ≥ÇÍÇΩç\ë¢ëÃÇ©ÇÁ PowerPC ÇÃîÒäˆî≠ê´ïÇìÆè¨êîì_ÉåÉWÉXÉ^Çïúå≥Ç∑ÇÈ
//
         
asm void RestorePowerPCVolatileFPRs(FPURegsPtr pFPURegsPtr)
{
 lfd fp0,  FPURegs.FPSCR(r3)             // ëfiîǵÇΩ fpscr Ç fp0 Ç…ÉçÅ[Éh
 mtfsf 0xff, fp0                           // ǪÇÍÇ fpscr Ç…ñflÇ∑
         
 lfd  fp0, FPURegs.FPR00(r3)
 lfd  fp1, FPURegs.FPR01(r3)
/*
 lfd  fp2, FPURegs.FPR02(r3)
 lfd  fp3, FPURegs.FPR03(r3)
 lfd  fp4, FPURegs.FPR04(r3)
 lfd  fp5, FPURegs.FPR05(r3)
 lfd  fp6, FPURegs.FPR06(r3)
 lfd  fp7, FPURegs.FPR07(r3)
 lfd  fp8, FPURegs.FPR08(r3)
 lfd  fp9, FPURegs.FPR09(r3)
 lfd  fp10, FPURegs.FPR10(r3)
 lfd  fp11, FPURegs.FPR11(r3)
 lfd  fp12, FPURegs.FPR12(r3)
 lfd  fp13, FPURegs.FPR13(r3)
*/
 blr
}
#endif // #if TARGET_CPU_PPC
         

óvñÒ

PowerPC ÇÃïÇìÆè¨êîì_ÉåÉWÉXÉ^ÇÕäÑÇËçûÇ›éûÇ…égópÇ∑ÇÈDZÇΔÇ™Ç≈Ç´Ç‹Ç∑ÅBÇΩÇæÇµÅAÉfÉxÉçÉbÉpÇÕäÑÇËçûÇ›ÉRÅ[ÉhÇÃç≈èâÇΔç≈å„Ç≈Ç∑Ç◊ǃÇÃîÒäˆî≠ê´ÉåÉWÉXÉ^ÇÃëfiîÇΔïúå≥ÇñYÇÍǃÇÕÇ¢ÇØÇ‹ÇπÇÒÅB


éQçlï∂å£



çXêVì˙: 1999 îN 3 åé 15 ì˙